<?php

namespace IDock\Insurance\CHAC\Response;

use Exception;
use IDock\Common\Tools\XMLTools;
use IDock\Http\Response;
use IDock\IDock\IDockEnums;
use IDock\Insurance\CHAC\CHACEnums;
use IDock\Insurance\CHAC\Request\DPremiumInquiryRequest;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\Premium\PremiumCoveragePrinter;
use IDock\Printer\Premium\PremiumInquiryPrinter;
use IDock\Visitor\Premium\PremiumCoverageVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;

class DPremiumInquiryResponse extends AllCHACResponse
{

    /*** @var PremiumInquiryPrinter $printer */
    public $printer = PremiumInquiryPrinter::class;

    /**
     * @var PremiumInquiryVisitor $visitor
     */
    public $visitor = PremiumInquiryVisitor::class;

    protected $records = [];

    public function resolve(): Response
    {
        $data = $this->getBody();

        $this->result = $data;

        preg_match('/<return>(.*)<\/return>/',$data,$matches);

        $body = $matches[0] ?? [];

        if (!$body) {
            $this->setError('数据格式错误');
        }

        $body = XMLTools::XmlToArray($body,['Kind'])['return']['policyFeeCountResponseBody'] ?? [];

        $this->setBody($body);

        $responseCode = $body['Head']['responseCode'] ?? '';
        $errorMessage = $body['Head']['errorMessage'] ?? '';

        if ($this->printer) {
            $this->printer = new $this->printer;
        }

        //交强险重复投保
        $this->ciRepeat($errorMessage);

        if ($this->printer->repeatInsuredFlg) {
            return $this;
        }

        if ($responseCode != '0000') {
            $this->setError($errorMessage);
            return $this;
        }

        return $this;
    }

    /**
     * 生成核保数据
     * @param DPremiumInquiryRequest $request
     * @return void
     * @throws Exception
     */
    public function bindUnderWritingData(DPremiumInquiryRequest $request) {
        $underwritingData = $request->generate();
        $this->printer->argc['underwritingData'] = $underwritingData;
    }

    public function printerInit(): Response
    {
        $data = $this->getBody();
        $orderNumber = '';
        $sunlightScore = '';

        $this->biRepeat($data['Head']['errorMessage'] ?? '');

        $biPremium = $data['CommRisk']['BasePart']['sumPremuim'] ?? '';

        //商业险强验证
        if ($biPremium and $this->printer->repeatInsuredFlg) {
            $this->printer->repeatInsuredFlg = true;
            $this->printer->success = false; //强验证
        }

        if ($this->printer->repeatInsuredFlg) {
            return $this;
        }

        //交强险
        if ($compRisk = $data['CompRisk'] ?? []) {
            $orderNumber = $compRisk['Ftrno']['orderNumber'] ?? '';
            $this->printer->ciInquiryNo = $orderNumber;

            $this->printer->ciPremiumPrinter->ciPremium = $compRisk['BasePart']['sumPremuim'] ?? '';
            $this->printer->ciPremiumPrinter->ciBasePremium = $compRisk['BasePart']['benchmarkPremium'] ?? '';
            $this->printer->ciPremiumPrinter->ciDiscount = $compRisk['BasePart']['discount'] ?? '';
            $this->printer->ciPremiumPrinter->ciStartData = $this->visitor->getCiStartData();
            $this->printer->ciPremiumPrinter->ciEndData = $this->visitor->getCiEndData();

            if ($this->printer->ciPremiumPrinter->ciDiscount) {
                $this->printer->ciPremiumPrinter->ciDiscount /= 100;
            }

            $this->printer->premiumFactorPrinter->TCIFactorAppend('交强上年出险次数','CIClaimsNum',$compRisk['BasePart']['claimsNum'] ?? '');

            $this->printer->carTaxPrinter->carShipTax = $compRisk['CarShipTax']['sumPayTax'] ?? '';
            $this->printer->carTaxPrinter->thisYearTax = $compRisk['CarShipTax']['sumPayTax'] ?? '';

            $sunlightScore = $compRisk['BasePart']['sunlightScore'] ?? '';
        }

        //商业险
        if ($commRisk = $data['CommRisk'] ?? []) {
            $orderNumber = $commRisk['Ftrno']['orderNumber'] ?? '';

            $this->printer->biInquiryNo = $orderNumber;

            $this->printer->biPremiumPrinter->biBasePremium = $commRisk['BasePart']['benchmarkPremium'] ?? '';
            $this->printer->biPremiumPrinter->biPremium = $commRisk['BasePart']['sumPremuim'] ?? '';
            $this->printer->biPremiumPrinter->biDiscount = $commRisk['BasePart']['discount'] ?? '';
            $this->printer->biPremiumPrinter->biStartData = $this->visitor->getBiStartData();
            $this->printer->biPremiumPrinter->biEndData = $this->visitor->getBiEndData();

            if ($this->printer->biPremiumPrinter->biDiscount) {
                $this->printer->biPremiumPrinter->biDiscount /=  100;
            }

            $orgCover = $this->visitor->coverageVisitorList;

            $orgCover = array_combine(array_column($orgCover,'coverageCode'),$orgCover);

            //商业险种
            foreach($commRisk['KindList']['Kind'] ?? [] as $item) {

                if ($item['kindCode'] == 'X') {
                    $item['kindCode'] = '14';
                }

                $coverageCode = array_search($item['kindCode'],CHACEnums::$coverageCode);

                if ($this->visitor->isNewEnergy) {
                    $coverageCode = 'C1' . substr($coverageCode, 2);
                }

                /*** @var PremiumCoverageVisitor $premiumCoverageVisitor */
                $premiumCoverageVisitor = $orgCover[$coverageCode];

                $premiumCoveragePrinter = new PremiumCoveragePrinter();

                $premiumCoveragePrinter->coverageCode = $coverageCode;
                $premiumCoveragePrinter->amount = $premiumCoverageVisitor->amount;
                $premiumCoveragePrinter->unitAmount = $premiumCoverageVisitor->unitAmount;
                $premiumCoveragePrinter->coverageName = IDockEnums::$coverageCode[$coverageCode];
                $premiumCoveragePrinter->serviceTimes = $premiumCoverageVisitor->serviceTimes;

                $premiumCoveragePrinter->premium = $item['grossPremium'] ?? '';
                $premiumCoveragePrinter->basePremium = $item['benchmarkPremium'];

                $this->printer->coverageListAppend($premiumCoveragePrinter);
            }

            if ($commRisk['BasePart']['fixedPriceRate'] ?? '') {
                $commRisk['BasePart']['fixedPriceRate'] /= 100;
            }

            if ($commRisk['BasePart']['entireRecommenDiscount'] ?? '') {
                $commRisk['BasePart']['entireRecommenDiscount'] = bcdiv($commRisk['BasePart']['entireRecommenDiscount'],'100',4);
            }

            $this->printer->premiumFactorPrinter->VCIFactorAppend('连续承保期间出险次数','BIClaimsNum',$commRisk['BasePart']['claimsNum'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('建议折扣','entireRecommenDiscount',$commRisk['BasePart']['entireRecommenDiscount'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('连续承保年数','insureYears',$commRisk['BasePart']['insureYears'] ?? '');

            $this->printer->premiumFactorPrinter->VCIFactorAppend('自主定价系数','selfPricingCoef',$commRisk['BasePart']['fixedPriceRate'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('短期费率','shortRate',$commRisk['BasePart']['shortRate'] ?? '');

            $this->printer->ncdFactor = $commRisk['BasePart']['profitRate'] ?? '';

            if ($this->printer->ncdFactor) {
                $this->printer->ncdFactor /= 100;
            }

            $sunlightScore = $commRisk['BasePart']['sunlightScore'] ?? '';
        }

        //壹账通系数
        if ($YztScore = $data['YztScore'] ?? []) {
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通评分百分段','YztCentile',$YztScore['centile'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通商业险纯损失','YztCommercialPureLost',$YztScore['commercialPureLost'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通预估标的终极赔付率','YztFinalLossrationRate',$YztScore['finalLossrationRate'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通交强险纯损失','YztForcePureLost',$YztScore['forcePureLost'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通标的纯损失','YztTargetPureLost',$YztScore['targetPureLost'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通升分主要因子','YztIncreaseFactor',$YztScore['increaseFactor'] ?? '');
            $this->printer->premiumFactorPrinter->ComFactorAppend('壹账通具体错误信息','YztErrorMessage',$YztScore['errorMessage'] ?? '');
        }

        //非车
        $this->noCar();
        $this->printer->inquiryNo = $orderNumber;

        $this->printer->premiumFactorPrinter->ComFactorAppend('光博车险分','sunlightScore',$sunlightScore);

        return $this;
    }

    /**
     * 非车
     * @return void
     */
    private function noCar()
    {
        if (!$this->visitor->getNonCarInquiryVisitor()->getNonCarList()) {
            return;
        }

        $this->printer->nonCarInquiryPrinter->loadVisitor($this->visitor->getNonCarInquiryVisitor()->getNonCarList());

        /*** @var $nonCarInquirySinglePrinter NonCarInquirySinglePrinter */
        $nonCarInquirySinglePrinter = $this->printer->nonCarInquiryPrinter->nonCarInquirySingleList[0];

        $this->printer->nonCarInquiryPrinter->totalPremium = $nonCarInquirySinglePrinter->premium;
    }

    /**
     * 交强险重复投保
     * @param $ciMessage
     * @return void
     */
    private function ciRepeat($ciMessage)
    {
        if (preg_match('/终保日期 ([\d\s:-]+)/', $ciMessage, $matches)) {
            if ($matches[1] ?? '') {
                $ciStartData = date('Y-m-d H:i:s', strtotime($matches[1]));
                $this->printer->repeatInsurePrinter['ciStartData'] = $ciStartData;
                $this->printer->repeatInsuredFlg = true;
                $this->printer->success = false;
                $this->printer->repeatMessage = $ciMessage;
            }
        }
    }

    /**
     * 商业险重复投保
     * @param $biMessage
     * @return void
     */
    private function biRepeat($biMessage) {

        if ($this->printer->repeatInsuredFlg) {
            return;
        }

        if (preg_match('/终保日期:([\d\s:-]+)/', $biMessage, $matches)) {
            if ($matches[1] ?? '') {
                $biStartData = date('Y-m-d H:i:s', strtotime($matches[1]));
                $this->printer->repeatInsurePrinter['biStartData'] = $biStartData;
                $this->printer->repeatInsuredFlg = true;
                $this->printer->success = false;
                $this->printer->repeatMessage = $biMessage;
            }
        }
    }
}
